package com.giantlizard.cloud.aspect;

import cn.hutool.json.JSONUtil;
import com.giantlizard.cloud.base.utils.IpUtil;
import com.giantlizard.cloud.annotation.LogRecord;
import com.giantlizard.cloud.base.entity.LogRecordData;
import com.giantlizard.cloud.utils.RabbitSendLogRecord;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.time.LocalDateTime;

/**
 * 日志记录切面
 * @author 康东伟
 * @since  2023/04/10 21:56
 */
@Component
@Aspect
@Slf4j
public class LogRecordAspect {
    private final RabbitSendLogRecord sendLogRecord;

    public LogRecordAspect(RabbitSendLogRecord sendLogRecord) {
        this.sendLogRecord = sendLogRecord;
    }

    /**
     * 操作日志切面
     * @param joinPoint 切面数据
     * @return
     * @throws Throwable
     */
    @Around("@annotation(logRecord)")
    public Object doOperationLog(ProceedingJoinPoint joinPoint, LogRecord logRecord) throws Throwable {
        MethodSignature signature= (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        LogRecord annotation = method.getAnnotation(LogRecord.class);
        if (!annotation.isOpen()){
            return joinPoint.proceed();
        }
        LogRecordData record = new LogRecordData();
        record.setDescription(annotation.description());
        long startTimeMills = System.currentTimeMillis();
        Object result = null;
        try {
            // 接收到请求，记录请求内容
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (attributes == null) {
                log.info("获取请求URL失败,可能为系统内部调用");
            } else {
                HttpServletRequest request = attributes.getRequest();
                // 记录下请求内容
                record.setRequestUrl(request.getRequestURL().toString());
                record.setRequestIp(IpUtil.getIpAddress(request));
                record.setRequestType(request.getMethod());
                record.setRequestTime(LocalDateTime.now().toString());
                record.setRequestMethod( joinPoint.getTarget().getClass().getName()
                        + "." + joinPoint.getSignature().getName());
                record.setRequestLocation("");
                record.setRequestStartTime(String.valueOf(startTimeMills));
                Object[] args = joinPoint.getArgs();
            }
            record.setIsException("0");
            //执行原有逻辑
            result = joinPoint.proceed();
        }catch (Exception e){
            record.setIsException("1");
            record.setExceptionMsg(e.toString());
        }
        finally {
            record.setRequestEndTime(String.valueOf(System.currentTimeMillis()));
            record.setRequestTime(String.valueOf(System.currentTimeMillis() -startTimeMills));
            if (result != null){
                record.setResultJson(JSONUtil.toJsonStr(result));
            }
        }
        sendLogRecord.sendLogRecord(record);
        return result;
    }
}
